home *** CD-ROM | disk | FTP | other *** search
- page 60,132
- ;TITLE (C) Copyright CAPROCK SYSTEMS, INC. 1982
- ;SUBTTL small-c:PC PC-DOS RUN TIME LIBRARY
- ;
- ;
- DATASEG SEGMENT BYTE PUBLIC 'code'
- DB '(C) Copyright CAPROCK SYSTEMS, INC. 1982'
- ;
- ;
- ;
- ;FOR I/O BUFFERS
- FCBSIZE EQU 40 ;PCDOS FCB SIZE + 3
- BUFFER EQU 4 ;SPACE NEEDED FOR NEXT PTR AND UNUSED CNT
- BUFSIZ EQU 512 ;DISK BLOCK SIZE
- NEXTP EQU 0 ;OFFSET IN BUFFER OF NEXT CHAR PTR
- UNUSED EQU 2 ;OFFSET IN BUFFER OF REMAINING CHARS
- FLAG EQU 37 ;OFFSET IN FCB OF FLAG TYPING AN FCB
- NBUFS EQU 4 ;NUMBER OF IOBUFS (SEE BELOW)
- FREEFLG EQU 128 ;FCB NOT ALLOCATED
- EOFFLG EQU 2 ;EOF ENCOUNTERED ON FILE
- WRTFLG EQU 1 ;FILE OPENED FOR WRITING
- CTRLZ EQU 26
- EOL EQU 13 ;END OF LINE CHARACTER
- LF EQU 10 ;LINE FEED
- ;
- ;PCDOS INT 21H FUNCTION CODES
- ;
- GETCH EQU 1
- PUTCH EQU 2
- GETSTR EQU 10
- SELECT EQU 14
- DMA EQU 26
- OPEN EQU 15
- DELETE EQU 19
- CREATE EQU 22
- CLOSE EQU 16
- SEQREAD EQU 20
- SEQWRITE EQU 21
- GETDFLT EQU 25 ;GET CURRENT LOGGED DRIVE
- PARSE EQU 41
- ;
- ;
- ; FCB STORAGE AND I/O BUFFERS
- ;
- DFLTDSK DB 0 ;BYTE FOR DEFAULT DISK
- IOBUFS DB FCBSIZE-3 DUP(?)
- DB FREEFLG,0,0
- DB BUFFER+BUFSIZ DUP(?)
- ;
- DB FCBSIZE-3 DUP(?)
- DB FREEFLG,0,0
- DB BUFFER+BUFSIZ DUP(?)
- ;
- DB FCBSIZE-3 DUP(?)
- DB FREEFLG,0,0
- DB BUFFER+BUFSIZ DUP(?)
- ;
- DB FCBSIZE-3 DUP(?)
- DB FREEFLG,0,0
- DB BUFFER+BUFSIZ DUP(?)
- DATASEG ENDS
- ;
- ;
- ;
- CSEG SEGMENT BYTE PUBLIC 'code'
- ASSUME CS:CSEG,DS:DATASEG
- ;-------------------------------------------------
- ;
- ; Small-C:PC Run Time Library for IBM PC-DOS
- ;
- ; V1 As of June, 1982
- ;
- ;--------------------------------------------------
- db '(C) Copyright CAPROCK SYSTEMS, INC. 1982'
- ;
- ;
- ; Fetch byte at offset BX in Stack Segment (SS) and sign extend into BX
- ;
- PUBLIC CCGCHAR
- CCGCHAR:
- MOV BP,BX
- MOV AL,[BP]
- CBW
- MOV BX,AX
- RET
- ;
- ; Fetch a 16-bit integer at offset BX in SS into BX
- ;
- PUBLIC CCGINT
- CCGINT:
- MOV BP,BX
- MOV BX,[BP]
- RET
- ;
- ; Store BL into SS at offset in DX
- ;
- PUBLIC CCPCHAR
- CCPCHAR:
- MOV BP,DX
- MOV [BP],BL
- RET
- ;
- ; Store BX into SS at Offset in DX
- ;
- PUBLIC CCPINT
- CCPINT:
- MOV BP,DX
- MOV [BP],BX
- RET
- ;
- ; Multiply DX by BX and return result in BX
- ;
- PUBLIC CCMULT
- CCMULT:
- MOV AX,DX
- IMUL BX
- MOV BX,AX
- RET
- ;
- ; Divide DX by BX, return quotient in BX, remainder in DX
- ;
- PUBLIC CCDIV
- CCDIV:
- MOV AX,DX
- MOV CX,1
- IMUL CX
- IDIV BX
- MOV BX,AX
- RET
- ;
- ; Unsigned compare of DX to BX, carry set if DX < BX
- ;
- PUBLIC CCUCMP
- CCUCMP:
- CMP DH,BH
- JNZ CC@1
- CMP DL,BL
- CC@1:
- MOV BX,1
- RET
- ;
- ; Test if DX >= BX (Unsigned)
- ;
- PUBLIC CCUGE
- CCUGE:
- CALL CCUCMP
- JNC CC@2
- DEC BX
- CC@2:
- RET
- ;
- ; Test if DX < BX (Unsigned)
- ;
- PUBLIC CCULT
- CCULT:
- CALL CCUCMP
- JC CC@3
- DEC BX
- CC@3:
- RET
- ;
- ; Test if DX > BX (Unsigned)
- ;
- PUBLIC CCUGT
- CCUGT:
- XCHG BX,DX
- CALL CCULT
- RET
- ;
- ; Test if DX <= BX (Unsigned)
- ;
- PUBLIC CCULE
- CCULE:
- XCHG BX,DX
- CALL CCUGE
- RET
- ;
- ; Signed Compare of DX and BX
- ;
- ; carry set if DX < BX, zero/non-zero set for equality
- ;
- PUBLIC CCCMP
- CCCMP:
- SUB DL,BL
- SBB DH,BH
- MOV BX,1
- JS CCCMP1
- OR DH,DL
- RET
- CCCMP1:
- OR DH,DL
- STC
- RET
- ;
- ; Test if DX = BX and set BX=1 if true, else 0
- ;
- PUBLIC CCEQ
- CCEQ:
- CALL CCCMP
- JZ CC@4
- DEC BX
- CC@4:
- RET
- ;
- ;
- ; Test if DX != BX
- ;
- PUBLIC CCNE
- CCNE:
- CALL CCCMP
- JNZ CC@5
- DEC BX
- CC@5:
- RET
- ;
- ; Test if DX < BX
- ;
- PUBLIC CCLT
- CCLT:
- CALL CCCMP
- JC CC@6
- DEC BX
- CC@6:
- RET
- ;
- ; Test if DX > BX
- ;
- PUBLIC CCGT
- CCGT:
- XCHG BX,DX
- CALL CCLT
- RET
- ;
- ; Test if DX <= BX
- ;
- PUBLIC CCLE
- CCLE:
- CALL CCCMP
- JC CC@7
- JZ CC@7
- DEC BX
- CC@7:
- RET
- ;
- ; Test if DX >= BX
- ;
- PUBLIC CCGE
- CCGE:
- XCHG BX,DX
- CALL CCLE
- RET
- ;
- ;-------------------------------------------------
- ;
- ; PC-DOS I/O MODULES
- ; (C) CAPROCK SYSTEMS, INC.
- ; P.O. BOX 13814
- ; ARLINGTON, TEXAS 76013
- ;
- ;-------------------------------------------------
- ;
- ;
- ;
- ; pcdos(ah,dx)
- ;
- PUBLIC QZPCDOS
- QZPCDOS:
- POP CX
- POP DX
- POP AX
- PUSH AX
- PUSH DX
- PUSH CX
- MOV AH,AL
- INT 21H
- CBW
- MOV BX,AX
- RET
- ;
- ;
- ; out808X(port,AL)
- ;
- ;
- PUBLIC QZOUT808X
- QZOUT808X:
- POP CX
- POP AX
- POP DX
- PUSH DX
- PUSH AX
- OUT DX,AL
- JMP CX
- ;
- ;
- ; int var = in808X(port)
- ;
- ;
- PUBLIC QZIN808X
- QZIN808X:
- POP CX
- POP DX
- PUSH DX
- IN AL,DX
- CBW
- MOV BX,AX
- JMP CX
- ;
- ;
- ; VIDEO I/O THRU ROM BIOS
- ;
- ; int10(AH,AL,BH,BL,CH,CL,DH,DL);
- ;
- ;
- PUBLIC QZINT10
- QZINT10:
- POP SI
- POP DX
- POP AX
- MOV DH,AL
- POP CX
- POP AX
- MOV CH,AL
- POP BX
- POP AX
- MOV BH,AL
- MOV DI,BX
- POP AX
- POP BX
- MOV AH,BL
- MOV BX,DI
- PUSH AX
- PUSH AX
- PUSH BX
- PUSH BX
- PUSH CX
- PUSH CX
- PUSH DX
- PUSH DX
- PUSH SI
- INT 10H
- RET
- ;
- ;
- ; ASYNC I/O THRU ROM BIOS
- ;
- ; BX = INT14(AH,AL,DX)
- ;
- PUBLIC QZINT14
- QZINT14:
- POP CX
- POP DX
- POP BX
- POP AX
- PUSH AX
- PUSH BX
- PUSH DX
- MOV AH,AL
- MOV AL,BL
- INT 14H
- MOV BX,AX
- JMP CX
- ;
- ;
- ; copy program prefix to stack area
- ;
- ; copyprefix(ptr);
- ;
- PUBLIC QZCOPYPREF
- QZCOPYPREF:
- POP CX
- POP DI ;OFFSET INTO STACK OF DESTINATION
- PUSH DI
- PUSH CX
- MOV AX,SS
- PUSH ES
- MOV ES,AX ;PREPARE FOR MOVE
- MOV SI,0
- CLD
- MOV CX,128 ;NUMBER WORDS TO MOVE
- REP MOVSW
- POP ES
- RET
- ;
- ;
- ; SOUND BELL
- ;
- ; bell()
- ;
- PUBLIC QZBELL
- QZBELL:
- MOV AX,7 ;BELL CHARACTER
- PUSH AX
- CALL QZPUTCHAR ;SOUND IT
- POP AX
- RET
- ;
- ;
- ; CLEAR SCREEN
- ;
- ; clrscreen();
- ;
- PUBLIC QZCLRSCREE
- QZCLRSCREE:
- INT 11H ;EQUIPMENT
- MOV SI,AX
- AND SI,30H
- MOV AX,0B800H ;COLOR CARD RAM
- MOV CX,8192 ;WORD COUNT
- CMP SI,30H
- JNE CC@8
- MOV AX,0B000H ;BW CARD RAM
- MOV CX,2048 ;WORD COUNT
- CC@8:
- MOV ES,AX
- MOV AH,15 ;VIDEO STATE
- INT 10H
- CMP AL,4 ;GRAPHICS MODE?
- JC CC@9
- CMP SI,30H ;BW CARD?
- JE CC@9
- XOR AX,AX ;FILL WORD
- JMP SHORT CC@10
- CC@9:
- MOV AX,' '+7*256 ;FILL WORD
- CC@10:
- XOR DI,DI
- CLD
- REP STOSW ;CLEAR VIDEO MEMORY
- MOV AH,2 ;MOVE CURSOR
- XOR DX,DX ;0,0 (HOME)
- XOR BH,BH ;ACTIVE PAGE
- INT 10H
- RET
- ;
- ;
- ;
- ; gets(buff)
- ;
- ;
- PUBLIC QZGETS
- QZGETS:
- POP BX
- POP DX
- PUSH DX
- PUSH BX
- SUB DX,2
- MOV BP,DX
- MOV CX,[BP]
- MOV AX,004FH ;ASSUMED LENGTH = 80 CHARS - 1 FOR EOL
- MOV [BP],AX ;SET UP BUFFER THE WAY PC-DOS WANTS IT
- PUSH DS
- MOV AX,SS
- MOV DS,AX
- MOV AH,GETSTR
- INT 21H
- POP DS
- MOV AX,[BP] ;LENGTH IN AH
- MOV [BP],CX ;RESTORE SAVED BYTES
- ADD BP,2
- MOV BX,BP
- MOV AL,AH
- CBW
- ADD BP,AX
- XOR AL,AL
- MOV [BP],AL ;INSERT C:PC STRING TERMINATOR
- CALL PUTLF
- RET
- ;
- PUTLF:
- MOV AH,PUTCH
- MOV DL,LF
- INT 21H
- RET
- ;
- ;
- ; getchar()
- ;
- ;
- PUBLIC QZGETCHAR
- QZGETCHAR:
- MOV AH,GETCH
- INT 21H
- MOV BL,AL
- XOR BH,BH
- CMP AL,CTRLZ
- JNZ GETC1
- MOV BX,-1
- GETC1:
- CMP AL,EOL
- JNZ GC2
- CALL PUTLF
- GC2:
- RET
- ;
- ;
- ; putchar(c)
- ;
- ;
- PUBLIC QZPUTCHAR
- QZPUTCHAR:
- POP BX
- POP DX
- PUSH DX
- PUSH BX
- MOV AH,PUTCH
- INT 21H
- MOV BL,DL
- CMP DL,EOL
- JNZ PUTC1
- CALL PUTLF
- PUTC1:
- XOR BH,BH
- RET
- ;
- ;
- ; puts(cp)
- ;
- ;
- PUBLIC QZPUTS
- QZPUTS:
- POP CX
- POP BP
- PUSH BP
- PUSH CX
- MOV AH,PUTCH
- PS1:
- MOV DL,[BP]
- OR DL,DL
- JNZ PS2
- RET
- PS2:
- INC BP
- INT 21H
- JMP PS1
- ;
- ;
- ; Run Time Initialize
- ;
- ;
- CCGO:
- MOV CL,4 ;SHIFT COUNT
- MOV AX,STACK
- MOV SS,AX
- MOV BX,DS
- SUB AX,BX
- SAL AX,CL ;MAKE DIFF 16 BITS
- NEG AX
- ADD AX,DS:6
- MOV SP,AX ;MAX STACK POINTER
- PUSH DS ;SAVE PREFIX ADDR
- SUB AX,AX
- PUSH AX ;LONG EXIT ADDRESS IS NOW ON TOP
- MOV AX,DATASEG
- PUSH DS
- MOV DS,AX
- MOV AH,GETDFLT
- INT 21H
- INC AL
- MOV BX,OFFSET DFLTDSK
- MOV [BX],AL
- POP DS
- EXTRN QZMAIN:NEAR
- CALL QZMAIN ;EXECUTE USER'S small-c:PC PROGRAM
- ; FALL THRU TO EXIT CODE
- ;
- ;
- ; exit()
- ;
- PUBLIC QZEXIT
- QZEXIT:
- MOV CL,4
- MOV AX,SS
- MOV BX,DS
- SUB AX,BX
- SAL AX,CL
- NEG AX
- ADD AX,DS:6
- SUB AX,4
- MOV SP,AX ;PRUNE STACK
- MOV AX,DATASEG
- PUSH DS
- MOV DS,AX
- MOV BX,OFFSET DFLTDSK
- MOV DL,[BX]
- DEC DL
- MOV AH,SELECT
- INT 21H
- POP DS
- DB 0CBH ;LONG RETURN TO DOS
- ;
- ;
- ; fopen(name,mode)
- ;
- PUBLIC QZFOPEN
- QZFOPEN:
- POP AX
- POP CX ;MODE
- POP SI ;PREPARE FOR PARSE
- PUSH SI
- PUSH CX
- PUSH AX
- PUSH CX ;SAVE MODE
- CALL GRABIO ;GET FCB
- POP CX ;RESTORE MODE FOR LATER USE
- OR BX,BX ;ANY LUCK IN GETTING AN FCB?
- JNZ FO1
- RET ;NOPE
- FO1:
- MOV DX,BX ;SAVE OFFSET
- PUSH DS ;SAVE CALLER'S DS
- MOV AX,DATASEG
- MOV DS,AX ;ADDRESS OUR DATA SEGMENT
- ADD BX,FCBSIZE ;OFFSET OF BUFFER
- MOV AX,BX
- ADD AX,BUFFER ;IO AREA OFFSET
- MOV [BX]+NEXTP,AX ;NEXT AVAILABLE CHAR
- PUSH DS
- MOV AX,DS
- MOV ES,AX
- MOV DI,DX ;ES:DI -> FCB
- MOV AX,SS
- MOV DS,AX ;DS:SI -> NAME
- MOV AH,PARSE
- XOR AL,AL ;PARSE WITHOUT SKIPPING ANYTHING
- INT 21H
- POP DS ;RESTORE OUR DS
- OR AL,AL ;ANY LUCK?
- JNZ FORET ;JUMP IF NOT
- MOV AL,[DI]+1 ;SEE IF WE HAD A VALID FILENAME
- CMP AL,20H ;BLANK?
- JNZ FO2 ;NOPE, SO IT MUST BE SOMETHING THERE
- FORET:
- POP DS ;RESTORE CALLER'S DS
- XOR BX,BX ;SET RETURN STATUS
- RET ;LEAVE
- FO2:
- MOV BX,DX ;RESTORE OFFSET OF FCB
- MOV AL,[BX] ;DRIVE
- PUSH DX ;SAVE ACCROSS CALL
- PUSH CX
- PUSH AX
- CALL PCDOSDSK ;SELECT IT
- POP AX
- POP BP ;MODE OFFSET INTO BP FOR STACK ACCESS
- POP DX
- MOV AL,[BP] ;GET MODE CHAR
- CMP AL,72H ;MODE='r'
- JZ FO3
- CMP AL,52H ;MODE='R'
- JNZ FO5
- FO3:
- MOV AH,OPEN
- INT 21H ;OPEN THE FILE
- OR AL,AL
- JZ FO4 ;NO ERROR JUMP
- FO3@1:
- PUSH DX ;FCB OFFSET
- CALL FREEIO ;GIVE IT UP
- POP DX
- JMP FORET
- FO4:
- XOR AX,AX
- FO4@1:
- MOV [BX]+FCBSIZE+UNUSED,AX ;SET UNUSED BUFFER BYTES
- XOR AX,AX
- MOV [BX]+32,AL ;INIT SOME FCB FIELDS
- MOV [BX]+33,AX
- MOV [BX]+35,AX
- MOV AX,BUFSIZ
- MOV [BX]+14,AX
- POP DS ;RESTORE CALLER'S DS
- RET ;LEAVE WITH BX SET TO FCB OFFSET
- FO5:
- CMP AL,77H ;MODE='w'
- JZ FO6
- CMP AL,57H ;MODE='W'
- JNZ FO3@1 ;TAKE ERROR EXIT
- FO6:
- MOV AH,DELETE
- INT 21H ;DELETE FILE IF IT CURRENTLY EXISTS
- MOV AH,CREATE
- INT 21H ;CREATE IT
- OR AL,AL ;OK?
- JNZ FO3@1 ;TAKE ERROR EXIT IF NOT
- MOV BX,DX
- MOV AL,WRTFLG
- MOV [BX]+FLAG,AL ;INDICATE HOW FILE IS OPENED
- MOV AX,BUFSIZ ;NUMBER OF UNUSED BUFFER POSITIONS
- JMP FO4@1
- ;
- ;
- ;
- ; grabio()
- ;
- ;
- GRABIO:
- PUSH DS
- MOV AX,DATASEG
- MOV DS,AX
- MOV BX,OFFSET IOBUFS+FLAG
- MOV CX,NBUFS
- MOV AL,FREEFLG
- GI1:
- CMP AL,[BX]
- JZ GI2
- ADD BX,FCBSIZE+BUFFER+BUFSIZ
- LOOP GI1
- XOR BX,BX
- JMP GI3
- GI2:
- XOR AL,AL
- MOV [BX],AL
- SUB BX,FLAG
- GI3:
- POP DS
- RET
- ;
- ;
- ;
- ; freeio(unit)
- ;
- ;
- FREEIO:
- POP CX
- POP BX
- PUSH BX
- MOV AL,FREEFLG
- MOV [BX]+FLAG,AL
- XOR BX,BX
- JMP CX
- ;
- ;
- ;
- ; pcdosdsk(drive)
- ;
- ;
- PCDOSDSK:
- POP CX
- POP DX
- PUSH DX
- OR DL,DL
- JNZ PD1
- ; SELECT DEFAULT DRIVE
- PUSH BX
- MOV BX,OFFSET DFLTDSK
- MOV DL,[BX]
- POP BX
- PD1:
- DEC DL
- MOV AH,SELECT
- INT 21H
- JMP CX
- ;
- ;
- ;
- ; fclose(unit)
- ;
- ;
- PUBLIC QZFCLOSE
- QZFCLOSE:
- POP CX
- POP BX ;FCB OFFSET
- PUSH BX
- PUSH CX
- MOV SI,1 ;DEFAULT RETURN CODE
- PUSH DS ;SAVE CALLER'S DS
- MOV AX,DATASEG
- MOV DS,AX
- MOV AL,WRTFLG
- AND AL,[BX]+FLAG ;OPENED FOR WRITE?
- JZ FC3 ;JUMP IF NOT
- MOV AX,CTRLZ
- PUSH AX ;CHAR TO WRITE
- PUSH BX ;UNIT TO GO TO
- CALL QZPUTC ;CTRLZ AT FILE END
- POP BX
- POP AX
- ; FILL BUFFER WITH FILL CHAR
- MOV DX,BX
- MOV AX,[BX]+FCBSIZE+NEXTP ;OFFSET OF NEXT AVAILABLE CHAR
- MOV CX,DX
- ADD CX,FCBSIZE+BUFFER+BUFSIZ ;OFFSET PAST LAST IOAREA BYTE
- SUB CX,AX ;NUMBER OF CHARS TO FILL
- PUSH CX ;SAVE UNUSED BYTE COUNT
- JLE FC0 ;JUMP IF NONE
- MOV DI,AX ;START ADDRESS ES:DI
- MOV AX,DS
- MOV ES,AX
- MOV AL,0 ;FILL CHAR
- CLD ;LEFT TO RIGHT
- REP STOSB ;FILL BUFFER
- FC0:
- MOV AX,SEQWRITE
- PUSH AX
- PUSH DX ;FUNCTION AND UNIT NOW ON STACK
- CALL PCDOSIO ;WRITE SECTOR
- MOV AX,BX ;SAVE RETURN CODE
- POP BX ;RESTORE UNIT
- POP CX
- OR AX,AX
- JNS FC1
- MOV SI,0
- FC1:
- POP CX ;RESTORE UNUSED COUNT
- NEG CX ;PREPARE TO REDUCE DOS COUNT
- JNS FC3 ;NO SIGN IMPLIES DOS COUNT IS OK
- MOV AX,1 ;PREPARE FOR OVERFLOW
- ADD [BX]+16,CX ;NEW LOW PART
- JNO FC3 ;NO OVERFLOW => NO HIGH PART CHANGE
- ADD [BX]+18,AX ;NEW HIGH PART
- FC3:
- MOV DX,BX
- MOV AH,CLOSE
- INT 21H ;CLOSE FILE
- OR AL,AL
- JNS FC2
- MOV SI,0
- FC2:
- PUSH BX
- CALL FREEIO
- POP BX
- POP DS
- MOV BX,SI
- RET
- ;
- ;
- ;
- ; pcdosio(fn,unit)
- ;
- ;
- PCDOSIO:
- POP CX
- POP DX ;UNIT= OFFSET IN DS OF FCB
- POP BX ;FUNCTION WANTED
- PUSH BX
- PUSH DX
- PUSH CX
- PUSH DS ;SAVE CALLER'S DS
- MOV AX,DATASEG
- MOV DS,AX
- XOR AH,AH
- XCHG BX,DX
- MOV AL,[BX] ;DRIVE NUMBER
- XCHG BX,DX
- PUSH DX
- PUSH AX
- CALL PCDOSDSK ;SELECT IT
- POP AX
- POP DX
- MOV CX,DX ;SAVE UNIT
- ADD DX,FCBSIZE+BUFFER ;IO AREA OFFSET
- MOV AH,DMA
- INT 21H ;SET TRANSFER ADDRESS
- MOV DX,CX ;DS:DX = FCB ADDRESS
- MOV AH,BL ;FUNCTION CODE
- INT 21H
- MOV CL,AL ;STATUS
- MOV AH,DMA
- POP DS ;RESET DS TO PREFIX
- MOV DX,80H
- INT 21H ;DMA BACK TO DEFAULT
- MOV AL,BL ;SAVE FUNCTION
- XOR BX,BX
- OR CL,CL
- JZ PDI1
- CMP AL,SEQREAD ;DID USER READ?
- JNZ PDI0 ;CONSIDER IT AN ERROR
- CMP CL,03H ;PARTIALLY FULL BUFFER?
- JZ PDI1 ;THAT'S OK
- PDI0:
- NOT BX
- PDI1:
- RET
- ;
- ;
- ;
- ; getc (unit)
- ;
- ;
- PUBLIC QZGETC
- QZGETC:
- POP CX
- POP BX ;UNIT
- PUSH BX
- PUSH CX
- PUSH BX
- CALL CGET ;GET NEXT CHARACTER
- POP DX ;UNIT
- CMP BL,EOL ;END OF LINE
- JNZ GC1 ;GO ON BACK IF NOT
- PUSH BX ;SAVE EOL ON STACK
- PUSH DX ;UNIT
- CALL CGET ;ABSORB LF
- POP DX
- POP BX ;RETURN EOL
- GC1:
- RET
- ;
- ;
- ;
- ; cget(unit)
- ;
- ;
- CGET:
- POP CX
- POP BX
- MOV DX,BX
- PUSH BX
- PUSH CX
- PUSH DS
- MOV AX,DATASEG
- MOV DS,AX
- MOV AL,EOFFLG
- AND AL,[BX]+FLAG ;END OF FILE EXIST?
- JZ CG1 ;NOPE
- CG0:
- POP DS
- MOV BX,-1 ;ERROR RETURN
- RET
- CG1:
- MOV AX,[BX]+FCBSIZE+NEXTP ;BUFFER OFFSET OF NEXT CHARACTER
- MOV CX,[BX]+FCBSIZE+UNUSED ;NUM CHARS REMAINING IN BUF
- OR CX,CX
- JNZ CG2 ;SOME LEFT
- ;READ NEW SECTOR
- MOV AX,SEQREAD
- PUSH AX ;FUNCTION
- PUSH DX ;UNIT
- CALL PCDOSIO ;READ SECTOR
- POP DX
- POP AX
- OR BH,BL ;OK?
- JNZ CG0 ;JUMP IF NOT
- MOV BX,DX ;RESTORE UNIT
- MOV CX,BUFSIZ ;NEW COUNT
- MOV AX,DX
- ADD AX,FCBSIZE+BUFFER ;NEW NEXT CHAR OFFSET
- CG2:
- DEC CX ;REDUCE UNUSED
- MOV [BX]+FCBSIZE+UNUSED,CX
- MOV CX,AX
- INC CX ;BUMP UP NEXT CHAR POINTER
- MOV [BX]+FCBSIZE+NEXTP,CX
- MOV BX,AX ;OFFSET OF CHAR TO RETURN
- MOV AL,[BX]
- CMP AL,CTRLZ ;IS IT EOF MARKER?
- JNZ CG3 ;JUMP IF NOT
- MOV BX,DX ;UNIT
- MOV AH,EOFFLG
- OR [BX]+FLAG,AH ;SET END OF FILE IN FCB
- JMP CG0
- CG3:
- MOV BL,AL ;CHAR TO RETURN
- XOR BH,BH
- POP DS
- RET
- ;
- ;
- ;
- ; putc(char,unit)
- ;
- ;
- ;
- PUBLIC QZPUTC
- QZPUTC:
- POP CX
- POP BX ;UNIT
- POP AX ;CHAR
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH AX ;CHAR
- PUSH BX ;UNIT
- CALL CPUT ;PUT OUT CHAR
- POP DX ;UNIT
- ;LEAVE CHAR ON STACK AS RETURN VALUE
- OR BH,BH ;ERROR?
- JS PC2 ;JUMP IF SO
- CMP BL,EOL ;DID EOL GO OUT?
- JNZ PC1 ;JUMP IF NOT
- MOV AX,LF ;PUT OUT LF ALSO
- PUSH AX
- PUSH DX
- CALL CPUT
- POP DX
- POP AX
- OR BH,BH ;ERROR?
- JS PC2 ;JUMP IF SO
- PC1:
- POP BX ;RETURN CHAR PASSED IN
- RET
- PC2:
- POP CX ;CLEAR CHAR OFF STACK
- MOV BX,-1 ;ERROR RETURN
- RET
- ;
- ;
- ;
- ; cput(c,unit)
- ;
- ;
- CPUT:
- POP CX
- POP BX ;UNIT
- POP SI ;CHAR
- PUSH SI
- PUSH BX
- PUSH CX
- PUSH DS
- MOV AX,DATASEG
- MOV DS,AX
- MOV DX,BX
- MOV AX,[BX]+FCBSIZE+NEXTP ;NEXT CHAR OFFSET
- MOV CX,[BX]+FCBSIZE+UNUSED ;UNUSED CHAR COUNT
- OR CX,CX
- JNZ CP2 ;JUMP IF ROOM AVAILABLE
- MOV AX,SEQWRITE
- PUSH AX ;FUNCTION
- PUSH DX ;UNIT
- CALL PCDOSIO ;SECTOR WRITE
- POP DX
- POP AX
- OR BH,BL
- JZ CP1 ;JUMP IF OK
- CP0:
- POP DS
- MOV BX,-1 ;ERROR RETURN
- RET
- CP1:
- MOV CX,BUFSIZ
- MOV AX,DX
- ADD AX,FCBSIZE+BUFFER
- MOV BX,DX
- CP2:
- DEC CX ;REDUCE UNUSED
- MOV [BX]+FCBSIZE+UNUSED,CX
- MOV CX,AX
- INC CX
- MOV [BX]+FCBSIZE+NEXTP,CX ;NEW NEXT CHAR OFFSET
- MOV BX,AX
- MOV AX,SI ;CHAR TO PUT
- MOV [BX],AL ;BUFFER CHARACTER
- MOV BX,AX
- POP DS
- RET
- ;
- CSEG ENDS
- STACK SEGMENT BYTE PUBLIC 'stack'
- STACK ENDS
- DUMMY SEGMENT BYTE STACK 'dummy'
- DB 128 DUP(?)
- DUMMY ENDS
- END CCGO
- Y ENDS
- END CCGO
-